// Copyright (c) 2021 Takeshi Ishii (mtei@github)
// SPDX-License-Identifier: MIT

// See here for how to use this. (https://github.com/mtei/bare_metal_parts/tree/master/cpp/map)

#pragma once
// clang-format off

#define _MAP1(E,ET, _1) ET(_1)
#define _MAP2(E,ET, _1,_2) E(_1) ET(_2)
#define _MAP3(E,ET, _1,_2,_3) E(_1) E(_2) ET(_3)
#define _MAP4(E,ET, _1,_2,_3,_4) E(_1) E(_2) E(_3) ET(_4)
#define _MAP5(E,ET, _1,_2,_3,_4,_5) E(_1) E(_2) E(_3) E(_4) ET(_5)
#define _MAP6(E,ET, _1,_2,_3,_4,_5,_6) E(_1) E(_2) E(_3) E(_4) E(_5) ET(_6)
#define _MAP7(E,ET, _1,_2,_3,_4,_5,_6,_7) E(_1) E(_2) E(_3) E(_4) E(_5) E(_6) ET(_7)
#define _MAP8(E,ET, _1,_2,_3,_4,_5,_6,_7,_8) E(_1) E(_2) E(_3) E(_4) E(_5) E(_6) E(_7) ET(_8)
#define _MAP9(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9) E(_1) E(_2) E(_3) E(_4) E(_5) E(_6) E(_7) E(_8) ET(_9)
#define _MAP10(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10) E(_1) E(_2) E(_3) E(_4) E(_5) E(_6) E(_7) E(_8) E(_9) ET(_10)
#define _MAP11(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11) E(_1) E(_2) E(_3) E(_4) E(_5) E(_6) E(_7) E(_8) E(_9) E(_10) ET(_11)
#define _MAP12(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12) E(_1) E(_2) E(_3) E(_4) E(_5) E(_6) E(_7) E(_8) E(_9) E(_10) E(_11) ET(_12)
#define _MAP13(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13) E(_1) E(_2) E(_3) E(_4) E(_5) E(_6) E(_7) E(_8) E(_9) E(_10) E(_11) E(_12) ET(_13)
#define _MAP14(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14) E(_1) E(_2) E(_3) E(_4) E(_5) E(_6) E(_7) E(_8) E(_9) E(_10) E(_11) E(_12) E(_13) ET(_14)
#define _MAP15(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15) E(_1) E(_2) E(_3) E(_4) E(_5) E(_6) E(_7) E(_8) E(_9) E(_10) E(_11) E(_12) E(_13) E(_14) ET(_15)
#define _MAP16(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16) E(_1) E(_2) E(_3) E(_4) E(_5) E(_6) E(_7) E(_8) E(_9) E(_10) E(_11) E(_12) E(_13) E(_14) E(_15) ET(_16)
#define _MAP17(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17) E(_1) E(_2) E(_3) E(_4) E(_5) E(_6) E(_7) E(_8) E(_9) E(_10) E(_11) E(_12) E(_13) E(_14) E(_15) E(_16) ET(_17)
#define _MAP18(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18) E(_1) E(_2) E(_3) E(_4) E(_5) E(_6) E(_7) E(_8) E(_9) E(_10) E(_11) E(_12) E(_13) E(_14) E(_15) E(_16) E(_17) ET(_18)
#define _MAP19(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19) E(_1) E(_2) E(_3) E(_4) E(_5) E(_6) E(_7) E(_8) E(_9) E(_10) E(_11) E(_12) E(_13) E(_14) E(_15) E(_16) E(_17) E(_18) ET(_19)
#define _MAP20(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20) E(_1) E(_2) E(_3) E(_4) E(_5) E(_6) E(_7) E(_8) E(_9) E(_10) E(_11) E(_12) E(_13) E(_14) E(_15) E(_16) E(_17) E(_18) E(_19) ET(_20)
#define _MAP21(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21) E(_1) E(_2) E(_3) E(_4) E(_5) E(_6) E(_7) E(_8) E(_9) E(_10) E(_11) E(_12) E(_13) E(_14) E(_15) E(_16) E(_17) E(_18) E(_19) E(_20) ET(_21)
#define _MAP22(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22) E(_1) E(_2) E(_3) E(_4) E(_5) E(_6) E(_7) E(_8) E(_9) E(_10) E(_11) E(_12) E(_13) E(_14) E(_15) E(_16) E(_17) E(_18) E(_19) E(_20) E(_21) ET(_22)
#define _MAP23(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23) E(_1) E(_2) E(_3) E(_4) E(_5) E(_6) E(_7) E(_8) E(_9) E(_10) E(_11) E(_12) E(_13) E(_14) E(_15) E(_16) E(_17) E(_18) E(_19) E(_20) E(_21) E(_22) ET(_23)
#define _MAP24(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24) E(_1) E(_2) E(_3) E(_4) E(_5) E(_6) E(_7) E(_8) E(_9) E(_10) E(_11) E(_12) E(_13) E(_14) E(_15) E(_16) E(_17) E(_18) E(_19) E(_20) E(_21) E(_22) E(_23) ET(_24)
#define _MAP25(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25) E(_1) E(_2) E(_3) E(_4) E(_5) E(_6) E(_7) E(_8) E(_9) E(_10) E(_11) E(_12) E(_13) E(_14) E(_15) E(_16) E(_17) E(_18) E(_19) E(_20) E(_21) E(_22) E(_23) E(_24) ET(_25)
#define _MAP26(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26) E(_1) E(_2) E(_3) E(_4) E(_5) E(_6) E(_7) E(_8) E(_9) E(_10) E(_11) E(_12) E(_13) E(_14) E(_15) E(_16) E(_17) E(_18) E(_19) E(_20) E(_21) E(_22) E(_23) E(_24) E(_25) ET(_26)
#define _MAP27(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27) E(_1) E(_2) E(_3) E(_4) E(_5) E(_6) E(_7) E(_8) E(_9) E(_10) E(_11) E(_12) E(_13) E(_14) E(_15) E(_16) E(_17) E(_18) E(_19) E(_20) E(_21) E(_22) E(_23) E(_24) E(_25) E(_26) ET(_27)
#define _MAP28(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28) E(_1) E(_2) E(_3) E(_4) E(_5) E(_6) E(_7) E(_8) E(_9) E(_10) E(_11) E(_12) E(_13) E(_14) E(_15) E(_16) E(_17) E(_18) E(_19) E(_20) E(_21) E(_22) E(_23) E(_24) E(_25) E(_26) E(_27) ET(_28)
#define _MAP29(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29) E(_1) E(_2) E(_3) E(_4) E(_5) E(_6) E(_7) E(_8) E(_9) E(_10) E(_11) E(_12) E(_13) E(_14) E(_15) E(_16) E(_17) E(_18) E(_19) E(_20) E(_21) E(_22) E(_23) E(_24) E(_25) E(_26) E(_27) E(_28) ET(_29)
#define _MAP30(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30) E(_1) E(_2) E(_3) E(_4) E(_5) E(_6) E(_7) E(_8) E(_9) E(_10) E(_11) E(_12) E(_13) E(_14) E(_15) E(_16) E(_17) E(_18) E(_19) E(_20) E(_21) E(_22) E(_23) E(_24) E(_25) E(_26) E(_27) E(_28) E(_29) ET(_30)
#define _MAP31(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31) E(_1) E(_2) E(_3) E(_4) E(_5) E(_6) E(_7) E(_8) E(_9) E(_10) E(_11) E(_12) E(_13) E(_14) E(_15) E(_16) E(_17) E(_18) E(_19) E(_20) E(_21) E(_22) E(_23) E(_24) E(_25) E(_26) E(_27) E(_28) E(_29) E(_30) ET(_31)
#define _MAP32(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32) E(_1) E(_2) E(_3) E(_4) E(_5) E(_6) E(_7) E(_8) E(_9) E(_10) E(_11) E(_12) E(_13) E(_14) E(_15) E(_16) E(_17) E(_18) E(_19) E(_20) E(_21) E(_22) E(_23) E(_24) E(_25) E(_26) E(_27) E(_28) E(_29) E(_30) E(_31) ET(_32)

#define SELECT_MAP(e,et,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,NAME,...) NAME
#define MAPT(E,ET,...) SELECT_MAP(E,ET,__VA_ARGS__,_MAP32,_MAP31,_MAP30,_MAP29,_MAP28,_MAP27,_MAP26,_MAP25,_MAP24,_MAP23,_MAP22,_MAP21,_MAP20,_MAP19,_MAP18,_MAP17,_MAP16,_MAP15,_MAP14,_MAP13,_MAP12,_MAP11,_MAP10,_MAP9,_MAP8,_MAP7,_MAP6,_MAP5,_MAP4,_MAP3,_MAP2,_MAP1)(E,ET,__VA_ARGS__)
#define MAP(E,...) MAPT(E,E,__VA_ARGS__)

#define _MAP_INDEX1(E,ET, _1) ET(0,_1)
#define _MAP_INDEX2(E,ET, _1,_2) E(0,_1) ET(1,_2)
#define _MAP_INDEX3(E,ET, _1,_2,_3) E(0,_1) E(1,_2) ET(2,_3)
#define _MAP_INDEX4(E,ET, _1,_2,_3,_4) E(0,_1) E(1,_2) E(2,_3) ET(3,_4)
#define _MAP_INDEX5(E,ET, _1,_2,_3,_4,_5) E(0,_1) E(1,_2) E(2,_3) E(3,_4) ET(4,_5)
#define _MAP_INDEX6(E,ET, _1,_2,_3,_4,_5,_6) E(0,_1) E(1,_2) E(2,_3) E(3,_4) E(4,_5) ET(5,_6)
#define _MAP_INDEX7(E,ET, _1,_2,_3,_4,_5,_6,_7) E(0,_1) E(1,_2) E(2,_3) E(3,_4) E(4,_5) E(5,_6) ET(6,_7)
#define _MAP_INDEX8(E,ET, _1,_2,_3,_4,_5,_6,_7,_8) E(0,_1) E(1,_2) E(2,_3) E(3,_4) E(4,_5) E(5,_6) E(6,_7) ET(7,_8)
#define _MAP_INDEX9(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9) E(0,_1) E(1,_2) E(2,_3) E(3,_4) E(4,_5) E(5,_6) E(6,_7) E(7,_8) ET(8,_9)
#define _MAP_INDEX10(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10) E(0,_1) E(1,_2) E(2,_3) E(3,_4) E(4,_5) E(5,_6) E(6,_7) E(7,_8) E(8,_9) ET(9,_10)
#define _MAP_INDEX11(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11) E(0,_1) E(1,_2) E(2,_3) E(3,_4) E(4,_5) E(5,_6) E(6,_7) E(7,_8) E(8,_9) E(9,_10) ET(10,_11)
#define _MAP_INDEX12(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12) E(0,_1) E(1,_2) E(2,_3) E(3,_4) E(4,_5) E(5,_6) E(6,_7) E(7,_8) E(8,_9) E(9,_10) E(10,_11) ET(11,_12)
#define _MAP_INDEX13(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13) E(0,_1) E(1,_2) E(2,_3) E(3,_4) E(4,_5) E(5,_6) E(6,_7) E(7,_8) E(8,_9) E(9,_10) E(10,_11) E(11,_12) ET(12,_13)
#define _MAP_INDEX14(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14) E(0,_1) E(1,_2) E(2,_3) E(3,_4) E(4,_5) E(5,_6) E(6,_7) E(7,_8) E(8,_9) E(9,_10) E(10,_11) E(11,_12) E(12,_13) ET(13,_14)
#define _MAP_INDEX15(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15) E(0,_1) E(1,_2) E(2,_3) E(3,_4) E(4,_5) E(5,_6) E(6,_7) E(7,_8) E(8,_9) E(9,_10) E(10,_11) E(11,_12) E(12,_13) E(13,_14) ET(14,_15)
#define _MAP_INDEX16(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16) E(0,_1) E(1,_2) E(2,_3) E(3,_4) E(4,_5) E(5,_6) E(6,_7) E(7,_8) E(8,_9) E(9,_10) E(10,_11) E(11,_12) E(12,_13) E(13,_14) E(14,_15) ET(15,_16)
#define _MAP_INDEX17(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17) E(0,_1) E(1,_2) E(2,_3) E(3,_4) E(4,_5) E(5,_6) E(6,_7) E(7,_8) E(8,_9) E(9,_10) E(10,_11) E(11,_12) E(12,_13) E(13,_14) E(14,_15) E(15,_16) ET(16,_17)
#define _MAP_INDEX18(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18) E(0,_1) E(1,_2) E(2,_3) E(3,_4) E(4,_5) E(5,_6) E(6,_7) E(7,_8) E(8,_9) E(9,_10) E(10,_11) E(11,_12) E(12,_13) E(13,_14) E(14,_15) E(15,_16) E(16,_17) ET(17,_18)
#define _MAP_INDEX19(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19) E(0,_1) E(1,_2) E(2,_3) E(3,_4) E(4,_5) E(5,_6) E(6,_7) E(7,_8) E(8,_9) E(9,_10) E(10,_11) E(11,_12) E(12,_13) E(13,_14) E(14,_15) E(15,_16) E(16,_17) E(17,_18) ET(18,_19)
#define _MAP_INDEX20(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20) E(0,_1) E(1,_2) E(2,_3) E(3,_4) E(4,_5) E(5,_6) E(6,_7) E(7,_8) E(8,_9) E(9,_10) E(10,_11) E(11,_12) E(12,_13) E(13,_14) E(14,_15) E(15,_16) E(16,_17) E(17,_18) E(18,_19) ET(19,_20)
#define _MAP_INDEX21(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21) E(0,_1) E(1,_2) E(2,_3) E(3,_4) E(4,_5) E(5,_6) E(6,_7) E(7,_8) E(8,_9) E(9,_10) E(10,_11) E(11,_12) E(12,_13) E(13,_14) E(14,_15) E(15,_16) E(16,_17) E(17,_18) E(18,_19) E(19,_20) ET(20,_21)
#define _MAP_INDEX22(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22) E(0,_1) E(1,_2) E(2,_3) E(3,_4) E(4,_5) E(5,_6) E(6,_7) E(7,_8) E(8,_9) E(9,_10) E(10,_11) E(11,_12) E(12,_13) E(13,_14) E(14,_15) E(15,_16) E(16,_17) E(17,_18) E(18,_19) E(19,_20) E(20,_21) ET(21,_22)
#define _MAP_INDEX23(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23) E(0,_1) E(1,_2) E(2,_3) E(3,_4) E(4,_5) E(5,_6) E(6,_7) E(7,_8) E(8,_9) E(9,_10) E(10,_11) E(11,_12) E(12,_13) E(13,_14) E(14,_15) E(15,_16) E(16,_17) E(17,_18) E(18,_19) E(19,_20) E(20,_21) E(21,_22) ET(22,_23)
#define _MAP_INDEX24(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24) E(0,_1) E(1,_2) E(2,_3) E(3,_4) E(4,_5) E(5,_6) E(6,_7) E(7,_8) E(8,_9) E(9,_10) E(10,_11) E(11,_12) E(12,_13) E(13,_14) E(14,_15) E(15,_16) E(16,_17) E(17,_18) E(18,_19) E(19,_20) E(20,_21) E(21,_22) E(22,_23) ET(23,_24)
#define _MAP_INDEX25(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25) E(0,_1) E(1,_2) E(2,_3) E(3,_4) E(4,_5) E(5,_6) E(6,_7) E(7,_8) E(8,_9) E(9,_10) E(10,_11) E(11,_12) E(12,_13) E(13,_14) E(14,_15) E(15,_16) E(16,_17) E(17,_18) E(18,_19) E(19,_20) E(20,_21) E(21,_22) E(22,_23) E(23,_24) ET(24,_25)
#define _MAP_INDEX26(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26) E(0,_1) E(1,_2) E(2,_3) E(3,_4) E(4,_5) E(5,_6) E(6,_7) E(7,_8) E(8,_9) E(9,_10) E(10,_11) E(11,_12) E(12,_13) E(13,_14) E(14,_15) E(15,_16) E(16,_17) E(17,_18) E(18,_19) E(19,_20) E(20,_21) E(21,_22) E(22,_23) E(23,_24) E(24,_25) ET(25,_26)
#define _MAP_INDEX27(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27) E(0,_1) E(1,_2) E(2,_3) E(3,_4) E(4,_5) E(5,_6) E(6,_7) E(7,_8) E(8,_9) E(9,_10) E(10,_11) E(11,_12) E(12,_13) E(13,_14) E(14,_15) E(15,_16) E(16,_17) E(17,_18) E(18,_19) E(19,_20) E(20,_21) E(21,_22) E(22,_23) E(23,_24) E(24,_25) E(25,_26) ET(26,_27)
#define _MAP_INDEX28(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28) E(0,_1) E(1,_2) E(2,_3) E(3,_4) E(4,_5) E(5,_6) E(6,_7) E(7,_8) E(8,_9) E(9,_10) E(10,_11) E(11,_12) E(12,_13) E(13,_14) E(14,_15) E(15,_16) E(16,_17) E(17,_18) E(18,_19) E(19,_20) E(20,_21) E(21,_22) E(22,_23) E(23,_24) E(24,_25) E(25,_26) E(26,_27) ET(27,_28)
#define _MAP_INDEX29(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29) E(0,_1) E(1,_2) E(2,_3) E(3,_4) E(4,_5) E(5,_6) E(6,_7) E(7,_8) E(8,_9) E(9,_10) E(10,_11) E(11,_12) E(12,_13) E(13,_14) E(14,_15) E(15,_16) E(16,_17) E(17,_18) E(18,_19) E(19,_20) E(20,_21) E(21,_22) E(22,_23) E(23,_24) E(24,_25) E(25,_26) E(26,_27) E(27,_28) ET(28,_29)
#define _MAP_INDEX30(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30) E(0,_1) E(1,_2) E(2,_3) E(3,_4) E(4,_5) E(5,_6) E(6,_7) E(7,_8) E(8,_9) E(9,_10) E(10,_11) E(11,_12) E(12,_13) E(13,_14) E(14,_15) E(15,_16) E(16,_17) E(17,_18) E(18,_19) E(19,_20) E(20,_21) E(21,_22) E(22,_23) E(23,_24) E(24,_25) E(25,_26) E(26,_27) E(27,_28) E(28,_29) ET(29,_30)
#define _MAP_INDEX31(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31) E(0,_1) E(1,_2) E(2,_3) E(3,_4) E(4,_5) E(5,_6) E(6,_7) E(7,_8) E(8,_9) E(9,_10) E(10,_11) E(11,_12) E(12,_13) E(13,_14) E(14,_15) E(15,_16) E(16,_17) E(17,_18) E(18,_19) E(19,_20) E(20,_21) E(21,_22) E(22,_23) E(23,_24) E(24,_25) E(25,_26) E(26,_27) E(27,_28) E(28,_29) E(29,_30) ET(30,_31)
#define _MAP_INDEX32(E,ET, _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32) E(0,_1) E(1,_2) E(2,_3) E(3,_4) E(4,_5) E(5,_6) E(6,_7) E(7,_8) E(8,_9) E(9,_10) E(10,_11) E(11,_12) E(12,_13) E(13,_14) E(14,_15) E(15,_16) E(16,_17) E(17,_18) E(18,_19) E(19,_20) E(20,_21) E(21,_22) E(22,_23) E(23,_24) E(24,_25) E(25,_26) E(26,_27) E(27,_28) E(28,_29) E(29,_30) E(30,_31) ET(31,_32)

#define SELECT_MAP_INDEX(e,et,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,NAME,...) NAME
#define MAPT_INDEX(E,ET,...) SELECT_MAP_INDEX(E,ET,__VA_ARGS__,_MAP_INDEX32,_MAP_INDEX31,_MAP_INDEX30,_MAP_INDEX29,_MAP_INDEX28,_MAP_INDEX27,_MAP_INDEX26,_MAP_INDEX25,_MAP_INDEX24,_MAP_INDEX23,_MAP_INDEX22,_MAP_INDEX21,_MAP_INDEX20,_MAP_INDEX19,_MAP_INDEX18,_MAP_INDEX17,_MAP_INDEX16,_MAP_INDEX15,_MAP_INDEX14,_MAP_INDEX13,_MAP_INDEX12,_MAP_INDEX11,_MAP_INDEX10,_MAP_INDEX9,_MAP_INDEX8,_MAP_INDEX7,_MAP_INDEX6,_MAP_INDEX5,_MAP_INDEX4,_MAP_INDEX3,_MAP_INDEX2,_MAP_INDEX1)(E,ET,__VA_ARGS__)
#define MAP_INDEX(E,...) MAPT_INDEX(E,E,__VA_ARGS__)

#define SELECT_ITEM_COUNT(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,NAME,...) NAME
#define GET_ITEM_COUNT(...) SELECT_ITEM_COUNT(__VA_ARGS__,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)
